home *** CD-ROM | disk | FTP | other *** search
- // CmArray.cpp
- // -----------------------------------------------------------------
- // Compendium - C++ Container Class Library
- // Copyright (C) 1992-1994, Glenn M. Poorman, All rights reserved
- // -----------------------------------------------------------------
- // Array implementation.
- // -----------------------------------------------------------------
-
- #include <stdlib.h>
- #include <cm/include/cmarray.h>
-
-
- // "CmArray" is the default array constructor.
- //
- CmArray::CmArray(unsigned sz, unsigned dt)
- {
- _delta = dt;
- _total = 0;
- _entries = (sz > 0) ? new CmObject*[sz] : NULL;
- _size = (_entries != NULL) ? sz : 0;
- }
-
-
- // "CmArray" is the array copy constructor.
- //
- CmArray::CmArray(const CmArray& A)
- {
- _delta = A._delta;
- _total = 0;
- _entries = (A._size > 0) ? new CmObject*[A._size] : NULL;
- _size = (_entries != NULL) ? A._size : 0;
- copy(A);
- }
-
-
- // "~CmArray" is the array destructor.
- //
- CmArray::~CmArray()
- {
- removeAll();
- delete[] _entries;
- }
-
-
- // "=" assignement operator copies the contents of the specified
- // array into this array.
- //
- CmArray& CmArray::operator=(const CmArray& A)
- {
- if (&A != this)
- {
- removeAll();
- delete[] _entries;
- _delta = A._delta;
- _total = 0;
- _entries = (A._size > 0) ? new CmObject*[A._size] : NULL;
- _size = (_entries != NULL) ? A._size : 0;
- copy(A);
- }
- return *this;
- }
-
-
- // "add" appends the specified object to the array.
- //
- Bool CmArray::add(CmObject* pObj)
- {
- if (!pObj) return FALSE;
- if (_total >= _size)
- if (_delta == 0 || !resize(_size+_delta))
- return FALSE;
- _entries[_total++] = pObj;
- return TRUE;
- }
-
-
- // "insertAt" inserts the specified object at the given index moving
- // the other objects to make room.
- //
- Bool CmArray::insertAt(int idx, CmObject* pObj)
- {
- if (!pObj || idx < 0 || idx >= _total) return FALSE;
- if (_total >= _size)
- if (_delta == 0 || !resize(_size+_delta))
- return FALSE;
-
- size_t sz = (_total - idx) * sizeof(CmObject*);
- memmove(&(_entries[idx+1]), &(_entries[idx]), sz);
- _entries[idx] = pObj;
- _total++;
- return TRUE;
- }
-
-
- // "replaceAt" replaces the object at the specified index with the
- // specified object.
- //
- Bool CmArray::replaceAt(int idx, CmObject* pObj)
- {
- if (!pObj || idx < 0 || idx >= _total) return FALSE;
- if (ownsObjects()) delete _entries[idx];
- _entries[idx] = pObj;
- return TRUE;
- }
-
-
- // "remove" removes the first occurrence of an object that isEqual to
- // the specified object from the array.
- //
- Bool CmArray::remove(CmObject* pObj)
- {
- if (_total == 0 || !pObj) return FALSE;
- int ii = 0;
- Bool found = FALSE;
- while (ii < _total && !found)
- if (_entries[ii++]->isEqual(pObj)) found = TRUE;
- return (found) ? removeAt(ii-1) : FALSE;
- }
-
-
- // "removeAt" removes the object at the specified index.
- //
- Bool CmArray::removeAt(int idx)
- {
- if (idx < 0 || idx >= _total) return FALSE;
-
- if (ownsObjects()) delete _entries[idx];
- size_t sz = (_total - idx + 1) * sizeof(CmObject*);
- memmove(&(_entries[idx]), &(_entries[idx+1]), sz);
- _entries[_total-1] = NULL;
- _total--;
- return TRUE;
- }
-
-
- // "index" returns the index of the first occurrence of an object
- // that isEqual to the specified object.
- //
- int CmArray::index(CmObject* pObj) const
- {
- if (_total == 0 || !pObj) return FALSE;
- int ii = 0;
- int idx = -1;
- while (ii < _total && idx == -1)
- if (_entries[ii++]->isEqual(pObj)) idx = ii-1;
- return idx;
- }
-
-
- // "lookup" returns the first occurrence of an object that isEqual
- // to the specified object.
- //
- CmObject* CmArray::lookup(CmObject* pObj) const
- {
- int idx = index(pObj);
- return (idx > -1) ? _entries[idx] : NULL;
- }
-
-
- // "occurrences" returns the number of objects in the array
- // isEqual to the specified object.
- //
- unsigned CmArray::occurrences(CmObject* pObj) const
- {
- if (_total == 0 || !pObj) return 0;
-
- int ii = 0;
- unsigned num = 0;
- while (ii < _total)
- if (_entries[ii++]->isEqual(pObj)) num++;
- return num;
- }
-
-
- // "removeAll" removes all objects from the array.
- //
- void CmArray::removeAll()
- {
- for (int ii = 0; ii < _total; ii++)
- {
- if (ownsObjects()) delete _entries[ii];
- _entries[ii] = NULL;
- }
- _total = 0;
- }
-
-
- // "resize" resizes the storage allocated for this array.
- //
- Bool CmArray::resize(unsigned newSize)
- {
- if (newSize == 0)
- {
- removeAll();
- delete[] _entries;
- _entries = NULL;
- _size = 0;
- return TRUE;
- }
-
- CmObject **newEntries = new CmObject*[newSize];
- if (!newEntries) return FALSE;
-
- if (newSize < _total)
- {
- for (int ii = newSize; ii < _total; ii++)
- if (ownsObjects()) delete _entries[ii];
- _total = newSize;
- }
-
- memmove(newEntries, _entries, _total * sizeof(CmObject*));
-
- delete[] _entries;
- _entries = newEntries;
- _size = newSize;
- return TRUE;
- }
-
-
- // "isEmpty" checks if the array is empty or not.
- //
- Bool CmArray::isEmpty() const
- {
- return (_total == 0);
- }
-
-
- // "quickSort" uses the standard library to perform a quick sort
- // on this array.
- //
- void CmArray::quickSort()
- {
- qsort(_entries, _total, sizeof(CmObject*), &CmArray::cmpObjs);
- }
-
-
- // "newIterator" creates and returns an array iterator.
- //
- CmIterator* CmArray::newIterator() const
- {
- return new CmArrayIterator(*this);
- }
-
-
- // "write" writes the array objects to the specified reserve file.
- //
- Bool CmArray::write(CmReserveFile& file) const
- {
- if (!writeBase(file)) return FALSE; // Write base container.
- if (!file.write(_delta)) return FALSE; // Write delta value.
- if (!file.write(_total)) return FALSE; // Write number of objects.
-
- Bool success = TRUE;
- int ii = 0;
- while (ii < _total && success) // For each object,
- success = _entries[ii++]->writeObject(file); // Write the object.
- return success;
- }
-
-
- // "read" reads the array objects from the specified reserve file.
- //
- Bool CmArray::read(CmReserveFile& file)
- {
- unsigned size = readBase(file); // Read base container.
-
- unsigned total;
- if (!file.read(_delta)) return FALSE; // Read delta value.
- if (!file.read(total)) return FALSE; // Read number of objects.
- if (!resize(size)) return FALSE; // Resize the array.
-
- removeAll();
-
- Bool success = TRUE;
- int ii = 0;
- while (ii < total && success) // For each object,
- {
- CmObject *pObj = CmObject::readObject(file); // Read object.
- if (pObj) success = add(pObj); ii++; // Add to array.
- }
- return success;
- }
-
-
- // "cmpObjs" is called by the standard library qsort function for
- // sorting the array into ascending order.
- //
- int CmArray::cmpObjs(const void* obj1, const void* obj2)
- {
- CmObject *pObj1 = *((CmObject**)obj1);
- CmObject *pObj2 = *((CmObject**)obj2);
- return pObj1->compare(pObj2);
- }
-